package com.swak.wechat;

import java.util.Map;

import com.swak.utils.Maps;
import com.swak.wechat.codec.SignUtils;

public interface MchConfig {

	/**
	 * 商户Id
	 *
	 * @return 商户Id
	 */
	String getMchId();

	/**
	 * 商户名称
	 *
	 * @return 商户名称
	 */
	String getMchName();

	/**
	 * 商户Key
	 *
	 * @return 商户Key
	 */
	String getMchKey();

	/**
	 * 签名类型
	 * 
	 * @return
	 */
	String getSignType();

	/**
	 * 回调地址 - 支付
	 *
	 * @return 回调地址
	 */
	String getPayNotifyUrl();

	/**
	 * 回调地址 - 退款
	 *
	 * @return 回调地址
	 */
	String getRefundNotifyUrl();

	/**
	 * 获得证书的配置
	 *
	 * @return 获得证书的配置
	 */
	byte[] getSslCertData();
	
	/**
	 * 获得证书的 MD5值
	 * 
	 * @return
	 */
	String getSslCertDataMD5();

	/**
	 * 是否使用沙箱测试: v2 支付现在不支持沙箱测试，需要升级到v3版本
	 *
	 * @return 是否使用沙箱测试
	 */
	default boolean isUseSandbox() {
		return false;
	}

	/**
	 * 修改商户Key - 沙箱测试时使用
	 *
	 * @param mchKey 修改商户Key
	 */
	void sandboxSetMchKey(String mchKey);

	/**
	 * Http 连接超时时间
	 *
	 * @return 连接超时时间
	 */
	default int getHttpConnectTimeoutMs() {
		return 6 * 1000;
	}

	/**
	 * Http 读取超时时间
	 *
	 * @return 读取超时时间
	 */
	default int getHttpReadTimeoutMs() {
		return 8 * 1000;
	}

	/**
	 * 处理请求
	 *
	 * @param xml xml格式数据
	 * @return 解析结果
	 */
	default Map<String, Object> process(String xml) {
		return this.process(xml, this.getSignType());
	}

	/**
	 * 处理请求
	 *
	 * @param xml      xml格式数据
	 * @param signType 签名类型
	 * @return 解析结果
	 */
	default Map<String, Object> process(String xml, String signType) {
		Map<String, Object> respData = Maps.fromXml(xml);
		String sign = String.valueOf(respData.get(Constants.FIELD_SIGN));
		if (Constants.SUCCESS.equals(respData.get(Constants.FIELD_RETURN_CODE))
				&& SignUtils.generateSign(respData, signType, this.getMchKey()).equals(sign)) {
			return respData;
		} else if(Constants.FAIL.equals(respData.get(Constants.FIELD_RETURN_CODE))) {
			throw new WechatErrorException(String.valueOf(respData.get(Constants.FIELD_RETURN_MSG)));
		}
		throw new WechatErrorException("签名验证失败");
	}
}
